package com.jwater.core.manager.worker.report;

import com.jwater.core.manager.common.model.ReportInfo;
import com.jwater.core.manager.worker.WorkerNodeImpl;
import com.jwater.core.metrics.GcInfo;
import com.jwater.core.metrics.JvmMetric;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @description:
 * @author: jnner
 * @createDate: 2021/3/5
 * @version: 1.0
 */
public class ReportMetric implements Runnable {
    protected static Logger logger = LoggerFactory.getLogger(ReportMetric.class);
    private Thread thread;
    private WorkerNodeImpl workerNode;
    private String host;
    private long uptime;
    private String key;

    public ReportMetric(WorkerNodeImpl workerNode, String host, long uptime, String key) {
        this.workerNode = workerNode;
        this.host = host;
        this.uptime = uptime;
        this.key = key;
    }

    public void start() {
        thread = new Thread(this);
        thread.start();
    }

    @Override
    public void run() {
        while (true) {
            try {
                ReportInfo reportInfo = collect(this.host, this.uptime, this.key);
                print(reportInfo);
                workerNode.report(reportInfo);
            } catch (Exception e) {
                logger.error(e.toString(), e);
            }
            synchronized (this) {
                try {
                    this.wait(45000);
                } catch (InterruptedException e) {
                    logger.error(e.toString(), e);
                }
            }
        }
    }

    public static ReportInfo collect(String host, long uptime, String key) {
        ReportInfo reportInfo = new ReportInfo();
        reportInfo.setKey(key);
        reportInfo.setHost(host);
        reportInfo.setPid(JvmMetric.pid());
        reportInfo.setHeapMemory(JvmMetric.getHeapMemory().get("size"));
        reportInfo.setNonHeapMemory(JvmMetric.getNonHeapMemory().get("size"));
        reportInfo.setLiveThreadCount(JvmMetric.getThreadCount().get("live"));
        reportInfo.setGcInfos(JvmMetric.getGcInfo());
        reportInfo.setUptime(uptime);
        return reportInfo;
    }

    public static void print(ReportInfo reportInfo) {
        StringBuilder sb = new StringBuilder();
        sb.append("heapMemory:").append(reportInfo.getHeapMemory())
                .append(",nonHeapMemory:").append(reportInfo.getNonHeapMemory())
                .append(",");
        for (GcInfo gcInfo : reportInfo.getGcInfos()) {
            sb.append(gcInfo.getGcName()).append(" gc-count=").append(gcInfo.getCollectionCount())
                    .append(" gc-time=").append(gcInfo.getCollectionTime()).append(",");
        }
        sb.append("liveThreadCount:").append(reportInfo.getLiveThreadCount());
        logger.info(sb.toString());
    }
}
